package com.zm.se.service.managerService.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.zm.se.entity.Emp;
import com.zm.se.entity.Manager;
import com.zm.se.listenner.EmpExcelListener;
import com.zm.se.mapper.managerMapper.ManagerMapper;
import com.zm.se.service.managerService.IManagerService;
import com.zm.se.service.managerService.ex.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.UUID;

@Service
public class ManagerServiceImpl implements IManagerService {
    @Autowired
    private ManagerMapper managerMapper;

    private Emp emp;



    @Override
    public int ExcelRead(String path,String filename) {
        int begin = managerMapper.selectCount(emp);
        //                                                文件路径         读出类型          监听器
        ExcelReader reader= EasyExcel.read(path+filename,Emp.class,new EmpExcelListener(managerMapper)).build();
        ReadSheet build = EasyExcel.readSheet(0).build();
        reader.read(build);
        reader.finish();
        int end = managerMapper.selectCount(emp);
        if (begin!=end){
            throw new InsertException("录入失败，请检查您的文件及格式是否符合录入要求");
        }
        return 1;


    }

    /**
     * 注册
     * @param manager  用户数据
     */
    @Override
    public void reg(Manager manager) {
        //打桩测试UserServiceImpl
        System.err.println("UserServiceImpl.reg()");
        System.err.println("注册的数据"+manager);
        /**
         * //判断这个用户是否已经注册了管理员
         * 如果结果大于零则该管理员已存在，不大于（等于）0则可以继续注册
         */
        if(managerMapper.findByNum(manager.getNum())!=null){
            throw new  UserNameDuplicateException("注册失败，尝试注册的工号:"+manager.getNum()+"已被占用！");
        }

        //准备执行加密，不全数据，加密后的密码，盐值
        String salt= UUID.randomUUID().toString();
        manager.setSalt(salt);
        String md5Password=getMd5Password(manager.getPassword(),salt);
        manager.setPassword(md5Password);
        Emp emp=managerMapper.findRegPwd(manager.getNum());
        System.out.println(emp);
        manager.setPhone(emp.getPhone());
        manager.setEmail(emp.getEmail());
        //补全数据：四项日志
        Date now=new Date();
        manager.setCreatedUser(manager.getUsername());
        manager.setModifiedUser(manager.getUsername());
        manager.setCreatedTime(now);
        manager.setModifiedTime(now);
        //打桩测试UserServiceImpl

        System.err.println("注册的数据"+manager);

        /**
         * 判断学校员工表是否有这名员工
         * 如果值大于0则有这名员工可以注册成为管理员，若没有则报错
         */
        if(managerMapper.findEmp(manager.getUsername(),manager.getNum())>0){
           if(managerMapper.mInsert(manager)>0){
               System.out.println("注册成功");

           }else {
               System.out.println("注册失败，执行注册时发生未知错误，请联系管理员！");
               throw new InsertException("注册失败，执行注册时发生未知错误，请联系管理员！");
           }
        }else{
            System.out.println("您不是本校员工！");
            throw new NoEmpException("注册失败，"+manager.getUsername()+"您不是本校员工！");
        }
    }

    /**
     * login
     * @param num  输入工号，查询条件
     * @param password  密码，记得加密后再比较
     * @return
     */
    @Override
    public Manager login(String num, String password) {
        //根据num查询该用户是否为管理员（看manager表里有没有，没有抛出异常managernotfoundexception）
        Manager manager=managerMapper.findByNum(num);
        if(manager==null){
            throw  new ManagerNotFoundException("该用户不是管理员");
        }
        //如果有，则获取到数据库中的密码和盐值
        String dbPassword=manager.getPassword();
        String salt=manager.getSalt();
        //加密前端密码并加密
        String Md5Password=getMd5Password(password,salt);
        //对比两个密码，如果不一致抛出异常PasswordMisMatchException
        if(!Md5Password.equals(dbPassword)){
            throw new PasswordMisMatchException("密码错误，请重试");
        }
        System.err.println("登陆成功");

        return manager;
    }


    /**
     * 修改信息
     * @param oldPassword   旧密码
     * @param newPassword   新密码
     * @param num   工号
     * @param phone 联系方式
     */
    @Override
    public void changeInfo(String oldPassword, String newPassword, String num,String phone,String email) {
        System.err.println("开始修改");
        //判断管理员表中是否有这个人
        Manager result=managerMapper.findByNum(num);

        //验证密码是否正确
        //获取盐值和数据库中的密码
        String salt=result.getSalt();
        String dbPassword=result.getPassword();
        //加密输入的原密码
        String Md5Password=getMd5Password(oldPassword,salt);
        //比较密码是否一致
        if(!Md5Password.equals(dbPassword)){
            throw new PasswordMisMatchException("密码错误，请重试");
        }
        //加密新密码
        String Md5NewPassword=getMd5Password(newPassword,salt);
        //修改密码
        if(managerMapper.updatePassword(num,Md5NewPassword,phone,email,result.getUsername(),new Date())==0
                && managerMapper.updateEmpPassword(num,phone,email)==0){
            throw new UpdateException("出现未知错误，修改失败，请联系管理员");
        }
        System.err.println("修改成功");

    }

    /**
     * 检查该员工是否为本单位员工，是否有权限借用
     * @param username
     * @param num
     * @return
     */
    @Override
    public void check(String username, String num) {
        Integer checkId=managerMapper.findByNumUsername(username,num);
        if (checkId!=1){
            throw new ManagerNotFoundException("您不是本单位员工,请再次检查否输入错误！");
        }
    }

    /**
     * 找回密码，获取邮箱
     * @param num
     * @return
     */
    @Override
    public String findPwd(String num) {
        Manager manager=managerMapper.findByNum(num);
        if (manager==null){
            throw new ManagerNotFoundException("您不是管理员，请正确填写工号");
        }
        return manager.getEmail();
    }
    /**
     * 注册获取邮箱
     * @param num
     * @return
     */
    @Override
    public String findRegPwd(String num) {
        Emp emp=managerMapper.findRegPwd(num);
        if (emp==null){
            throw new ManagerNotFoundException("您不是本单位员工，请正确填写工号");
        }
        return emp.getEmail();
    }


    /**
     * 密码加密方法
     * @param password  原始密码
     * @param salt  盐值
     * @return  加密后密码
     */
    private String getMd5Password(String password,String salt){
        /*
        加密规则：
            1.使用“盐值+密码+盐值”作为原文
            2.三重加密（把1过程执行三次）
         */
        System.err.println("原始密码："+password);
        System.err.println("盐值："+salt);
        for (Integer i=0;i<3;i++){
            //此方法由springframework提供//把字符串转换为字节数组.getBytes()
            password= DigestUtils.md5DigestAsHex((salt+password+salt).getBytes());
        }
        System.err.println("加密后密码："+password);
        return password;
    }


    @Override
    public Integer resetPwd(String num, String password) {
        Manager manager=managerMapper.findByNum(num);
        if (manager==null){
            throw new ManagerNotFoundException("您不是管理员，请正确填写工号");
        }
        String salt=manager.getSalt();
        String Md5NewPassword=getMd5Password(password,salt);
        //修改密码
        if(managerMapper.resetPwd(num,Md5NewPassword)==0){
            throw new UpdateException("出现未知错误，修改失败，请联系管理员");
        }
        System.err.println("修改成功");

        return 1;
    }


}
